package com.hzvdvmc.autosale.seriaport;

import android.text.TextUtils;

import com.hzvdvmc.autosale.MyApp;
import com.hzvdvmc.autosale.constant.SpKey;
import com.hzvdvmc.autosale.socket.manager.CheckNumUtil;
import com.hzvdvmc.autosale.util.LogUtil;
import com.hzvdvmc.autosale.util.SPUtils;
import com.hzvdvmc.autosale.util.StringUtil;
import com.hzvdvmc.autosale.util.ToastUtils;

import android_serialport_api.SeriaPortClient;

/**
 * Created by william on 2017/12/30.
 * 串口指令操作
 */

public class SeriaCmdRequestManager {
    private static SeriaCmdRequestManager instacne;
    private SeriaPortClient mClient;

    public String getFlowCode() {
        int flowCode = SPUtils.getInstance().getInt(SpKey.FLOW_CODE, 0);

        if (flowCode < 10) {
            return "000" + flowCode;
        }
        if (flowCode < 100) {
            return "00" + flowCode;
        }
        if (flowCode < 1000) {
            return "0" + flowCode;
        }
        return flowCode + "";
    }

    /**
     * 新增流水码
     *
     * @return
     */
    public static String getNewFlowCode() {
        int flowCode = SPUtils.getInstance().getInt(SpKey.FLOW_CODE, 0);
        flowCode++;
        if (flowCode == 9999) {
            flowCode = 0;
        }
        SPUtils.getInstance().put(SpKey.FLOW_CODE, flowCode);
        if (flowCode < 10) {
            return "000" + flowCode;
        }
        if (flowCode < 100) {
            return "00" + flowCode;
        }
        if (flowCode < 1000) {
            return "0" + flowCode;
        }
        return flowCode + "";
    }


    /**
     * 地址码
     *
     * @param tuneNO 货道号
     * @return
     */
    public String getAddressCode(String tuneNO) {
        if (TextUtils.isEmpty(tuneNO)) {
            return "";
        }
        String data = "";
        try {
            data = tuneNO.substring(0, 1);
            mClient = MyApp.portMap.get(data);
            switch (data) {
                case "A":
                    data = "00";
                    break;
                case "B":
                    data = "01";
                    break;
                case "C":
                    data = "02";
                    break;
                case "D":
                    data = "03";
                    break;

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;
    }

    public String getRank(String tuneNO) {
        if (TextUtils.isEmpty(tuneNO)) {
            return "";
        }
        String data = "";
        try {
            data = tuneNO.substring(2, 3);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;
    }

    public String getColumn(String tuneNO) {
        if (TextUtils.isEmpty(tuneNO)) {
            return "";
        }
        String data = "";
        try {
            data = tuneNO.substring(3);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;
    }

    public static SeriaCmdRequestManager getInstacne() {
        if (instacne == null) {
            instacne = new SeriaCmdRequestManager();

        }
        return instacne;
    }

    private SeriaCmdRequestManager() {

    }

    public void request(SerialCmdEnum cmd, String data) {
        LogUtil.i("serialport", "[--serail request --]:cmd=" + cmd + ",data=" + data);

        if (SerialCmdEnum.MACHINE_STATE == cmd) {
            sendCheckComand(data, getFullCommand(cmd, data));
            return;
        }

        sendComand(getFullCommand(cmd, data));
    }

    /**
     * 获取包头
     *
     * @param command
     * @param data
     * @return
     */
    private static String getHeader(SerialCmdEnum command, String data) {
        String start = SerialCmdEnum.START.getValue();
        String size = Integer.toHexString(data.length() + 1);
        //size是2个字节，也就是4位16进制
        //比如10进制16 那就是 000F,10进制4096 那就是0FFF
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 4 - size.length(); i++) {
            sb.append("0");
        }
        size = sb.toString() + size;
        String checkNum = CheckNumUtil.getCheckNum(command.getValue(), data);
        return start + size + checkNum;
    }


    /**
     * 发送数据
     *
     * @param str 16进制数据
     *            真实发送时是16进制数组
     *            比如234d
     */
    private void sendComand(final String str) {

        if (mClient != null) {
            mClient.write(StringUtil.hexStringToBytes(str));
        } else {
            ToastUtils.showShort("串口连接异常");
        }
    }


    private void sendCheckComand(String data, String fullCmd) {
        String key = "";
        switch (data) {
            case "00":
                key = "A";
                break;
            case "01":
                key = "B";
                break;
            case "02":
                key = "C";
                break;
            case "03":
                key = "D";
                break;
        }

        mClient = MyApp.portMap.get(key);
        if (mClient != null ) {
            LogUtil.i("serial","serial client:"+mClient.getFilePath());
            mClient.write(StringUtil.hexStringToBytes(fullCmd));
        } else {
            ToastUtils.showShort("串口连接异常");
        }
    }


    /**
     * 完整上传数据
     *
     * @param command 指令
     * @param data    中间的有效数据，需要转化成16进制
     * @return
     */
    public static String getFullCommand(SerialCmdEnum command, String data) {
        StringBuilder sb = new StringBuilder();
        sb.append(getHeader(command, data));
        //消息体command+data
//        String bodyMsg = EncodeUtil.encoded(command.getName() + StringUtil.convertStringToHex(data));
        String bodyMsg = command.getValue() + StringUtil.convertStringToHex(data);
        sb.append(bodyMsg);
        sb.append("ee");
        String fullComand = sb.toString();
        if (command != SerialCmdEnum.HEARTBEAT) {
            LogUtil.p("发送串口指令：" + command.getDesc());
        }
        LogUtil.i("[getFullCommand] 完整串口指令:" + command.getDesc() + "-> " + fullComand);
        return fullComand;
    }

    /**
     * 出货
     *
     * @param shopWayNo 货道编号
     */
    public String getDataOutWare(String shopWayNo, boolean isTest) {

        String test = "1";
        if (isTest) {
            test = "0";
        }
        String flowCode = getNewFlowCode();
        String data = getAddressCode(shopWayNo)
                + flowCode
                + getRank(shopWayNo)
                + getColumn(shopWayNo) + test;
        LogUtil.i("新流水码：" + flowCode + ";地址码：" + getAddressCode(shopWayNo));
        return data;
    }

    /**
     * 查询出货结果
     */
    public String getCheckDataWareResul(String shopWayNo) {
        LogUtil.i("查询出货 流水码：" + getFlowCode()
                + ",addresscode=" + getAddressCode(shopWayNo)
                + ",shopWayNo=" + shopWayNo);
        return getAddressCode(shopWayNo) + getFlowCode();
    }

    /**
     * 重启设备
     */
    public void restartRequest(String address) {
        sendComand(getFullCommand(SerialCmdEnum.ROMOTE_RESTART, address));
    }

    /**
     * 查询机器状态
     */
    public void checkMachineStateRequest(String address) {
        sendComand(getFullCommand(SerialCmdEnum.MACHINE_STATE, address));
    }

}
